#导入库
import datetime
import random#用于生成验证码


#用于操作按钮
from PyQt5.QtWidgets import QApplication,QMessageBox,QMainWindow
from PyQt5 import QtWidgets
#ui显示
from PyQt5.uic import loadUiType
#解释器交互
import sys
#连接数据库
import pymysql
#定时执行爬取京东top
from threading import Timer

#爬虫
import urllib.request
import urllib.error#相关报错
from PyQt5.QtWidgets import QHeaderView
from bs4 import BeautifulSoup #网页解析
import re #正则表达式，进行文字匹配


#人脸识别class
#opencv 函数
from cv2 import cv2
#操作系统
import os
#图像处理
from  PIL import Image
#数组
import  numpy as np

#人脸识别
import urllib
import urllib.request


#pyqt5用法
u1, _ =loadUiType('登陆界面.ui')
u2, _ =loadUiType('注册.ui')
u3, _ =loadUiType('忘记密码.ui')
u4, _ =loadUiType('商品管理.ui')
# main_win = None


class LoginWin(QMainWindow,u1):#类，登录界面

    def __init__(self):#对象初始化
        super(LoginWin,self).__init__()#子类继承父类init方法

        self.setupUi(self)
        # self.ui = loadUiType('登陆界面.ui')#登录界面路径加载
        self.pushButton_2 .clicked.connect(self.denglu)#按钮2连接登录后的管理界面
        self.pushButton.clicked.connect(self.zhuce)#按钮连接注册界面
        self.pushButton_4 .clicked.connect(self.wjmm)

        self.pushButton_3.clicked.connect(self.face)#人脸识别




    def denglu(self):#登录函数
        lj = pymysql.connect(host="localhost", user="root", passwd="z12j34y56", database="bigzy",
                             charset="utf8") #连接数据库
        cursor = lj.cursor()  # 定义游标
        sql = "select * from user where ur_zh = %s and ur_password = %s  "#sql语句
        a = self.dlusername.text()#获取用户名文本内容
        b = self.dlpassword.text()#获取秘密文本内容
        if len(a) == 0 or len(b) ==0:
            warning = QtWidgets.QMessageBox.warning(self, "登陆失败", "警告，用户名或密码为空",
                                                    QtWidgets.QMessageBox.Yes)  # 警告窗口
        else:
            cursor.execute(sql,(a, b))  # 执行sql语句
            data = cursor.fetchone()  # fetchone取其中一条数据
            if data:  # 如果存在数据，则执行以下功能
                self.w = Window_gl()#调用管理界面函数
                self.close()  # 当前窗口关闭
                self.w.show()  # 主窗口（管理界面）打开
            else:
                warning = QtWidgets.QMessageBox.warning(self, "登陆失败", "用户名或密码错误，是否重新登录？", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)#警告窗口
                if warning == QMessageBox.Yes:#判断，点击yes则进行下面操作
                    self.dlusername.setText('')  # 清空用户名重新登录
                    self.dlpassword.setText('') # 清空密码重新登陆
                if warning == QMessageBox.No:
                    QApplication.exit()#退出程序



    def zhuce(self):#注册界面的函数
        self.w = Window_zhuce()  # 调用注册界面函数
        self.close()  # 当前窗口关闭
        self.w.show()  # 主窗口（管理界面）打开

    def wjmm(self):
        self.w = Window_wjmm()  # 调用忘记密码界面函数
        self.close()  # 当前窗口关闭
        self.w.show()  # 主窗口（管理界面）打开

    def face(self):#人脸识别函数
        self.f = Face()
        self.close()



# 密码加密
def md5(str):
    import hashlib
    m = hashlib.md5()
    m.update(str.encode("utf8"))
    return m.hexdigest()
#注册界面类
class Window_zhuce(QtWidgets.QMainWindow,u2):
    global yzm_1#定义全局变量
    def __init__(self):
        super(Window_zhuce, self).__init__()  # 子类继承父类init方法

        self.setupUi(self)
        # self.ui = loadUiType('注册.ui')#显示注册界面

        self.pushButton_2.clicked.connect(self.fanhui)  # 从注册界面返回登录界面
        self.pushButton.clicked.connect(self.zhuceuser)  # 注册按钮与注册用户的函数相连接
        self.pushButton_3.clicked.connect(self.yzm) #验证码按钮连接yzm函数

#cv2的路径尽量不使用中文，不然有些路径不能查到
    # 图像输入，数据保存
    def shujubaocun(self):
        # 用于人脸识别的数据
        faceCascade = cv2.CascadeClassifier('./haarcascade_frontalface_alt2.xml')
        # 摄像头
        cap = cv2.VideoCapture(0)
        count1 = 1  # 第几张图片
        zcusername = self.zcusername.text()  # 用户名文本框内容获取  # 文本框获取
        while True:  # 死循环，不让摄像头一闪而逝

            ok, img = cap.read()  # 得到摄像头的图片img和状态，视频由一帧一帧图像构成
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 将img转换为灰度图像

            # 用来识别照片中的人脸
            face = faceCascade.detectMultiScale(
                gray,#识别要用灰度图像，显示出来才用彩色
                scaleFactor=1.05,  # 每次图像尺寸减小的比例，越大越检测不到
                minNeighbors=5,  # 检测五次，五次都有才能是人脸
                minSize=(32, 32)  # 图片最小尺寸
            )

            for (x, y, w, h) in face:  # 将face数组循环

                # 将数据保存到指定文件夹下 文件名为：user+数字+字符串.jpg
                cv2.imwrite("./faceinfo/user." + zcusername + '.' + str(count1) + ".jpg", gray[y:y + h, x:x + w])

                cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)  # 矩形，将人脸框起来，框选的目标，矩形的大小以及边框颜色和大小 依次对应
                # cv2.putText(img, 'zj', (x + w, y), font, 1, (255, 255, 0), 1) #显示矩形框的标识

                # count自动加一，用于下面判断，
                count1 += 1

            # 窗口显示
            cv2.imshow('cap', img)
            # 只拍摄50张照片
            if count1 >= 50:
                break
            # 窗口等待时间
            key = cv2.waitKey(1)
            # 如果想提前退出，按esc
            if key == 27:
                QtWidgets.QMessageBox.information(self, "提示", "未获取到全部照片，已退出",
                                              QtWidgets.QMessageBox.Yes)  # 消息提示框
                break
        cap.release()#关闭摄像头
        cv2.destroyAllWindows()#关闭cv2的所有窗口

    # 训练函数
    def xunlian(self):
        # zcusername = self.ui.zcusername.text()#用户名文本框内容获取  # 文本框获取
        # 加载训练器
        recognizer = cv2.face.LBPHFaceRecognizer_create()
        #加载分类器
        faceCascade = cv2.CascadeClassifier('./haarcascade_frontalface_alt2.xml')
        # 图片所在文件夹
        img_path = 'faceinfo'
        # 所有图片的路径
        all_img_paths = [os.path.join(img_path, f) for f in os.listdir(img_path)]

        # # 定义数组，用于存储数据
        ids = []
        face_samples = []

        #原本打算每个用户用一个yml文件，后来尝试过循环不通过，
        # 所以就每加一个用户都要进行全部图片的训练，增加了代码的计算量
        # new_img_paths = []
        # for eace_img in all_img_paths:
        #     id = os.path.split(eace_img)[1].split('.')[1]
        #
        #     if id == zcusername:
        #         new_img_paths.append(eace_img)


        # 循环每一张图片
        for eace_img in all_img_paths:
            # 获取id，并将他转换为整数型
            id = int(os.path.split(eace_img)[1].split('.')[1])

            # 把图片转换成训练所需要的格式数据 PIL_img是数组类型
            PIL_img = Image.open(eace_img).convert('L')  # 把图片转换为灰度数据
            np_img = np.array(PIL_img, 'uint8')  # 将灰度数据转换为8位数据的矩阵
            faces = faceCascade.detectMultiScale(np_img)  # 检测图片中是否有人脸

            for (x, y, w, h) in faces:  # 循环，分别将两个数据加入两个数组中
                face_samples.append(np_img[y:y + h, x:x + w])
                ids.append(id)

        #print(np.array(ids))
        # 训练自己数据
        recognizer.train(face_samples, np.array(ids))
        # 将数据写入yml文件
        recognizer.write('./trainer/people.yml')


    def fanhui(self):#定义返回登录界面的函数
        self.a=LoginWin()# a = 登录函数
        self.close()#关闭自己
        self.a.show()#打开登录


    def zhuceuser(self):  # 定义注册用户的函数
        lj = pymysql.connect(host="localhost", user="root", passwd="z12j34y56", database="bigzy",
                             charset="utf8")  # 连接数据库
        cursor = lj.cursor()  # 定义游标
        zcyhm = self.zcyhm.text()  # 实现从指定界面输入框获取指定输入信息
        zcusername = self.zcusername.text()#用户名文本框内容获取
        zcpassword1 = self.zcpassword1.text()#密码文本框内容获取
        zcpassword2 = self.zcpassword2.text()#再次确认密码
        zcphonenum = self.zcphonenum.text()#电话号码

        #查询账号是否重复
        sql = "select ur_zh from user"#sql
        cursor.execute(sql)#执行
        data = cursor.fetchall()# 得到全部数据
        # print(data[2])
        # print(type(data[2]))
        # print('('+ zcusername +',)')
        # print(type('('+ zcusername +',)'))
        # print(str(data[2]) == '('+ zcusername +',)')
        if len(zcyhm)==0 or len(zcusername)==0 or len(zcpassword1) ==0 or len(zcpassword2)==0 or len(zcphonenum)==0:#所有文本不可为空
            QtWidgets.QMessageBox.warning(self, "警告", "注册不可为空！", QtWidgets.QMessageBox.Yes)#消息提示框

        elif zcusername.isdigit() ==False:#判断账号中是不是只由数字组成，规定只能为数字，用于后面人脸识别
             QtWidgets.QMessageBox.warning(self, "警告", "账号只能由数字组成！", QtWidgets.QMessageBox.Yes)  # 消息提示框


        elif ( '('+ zcusername +',)') in str(data):#账号相同的情况，加（ ,）是因为元组数据转字符串带着
        #data数据类型为元组，zcusername的类型为字符串，所以需要转换类型
            QtWidgets.QMessageBox.warning(self, "警告", "账号已存在！", QtWidgets.QMessageBox.Yes)#消息提示框

        elif zcpassword1 == zcpassword2:     # 如果密码和确认密码相同，则执行以下代码
            if len(zcphonenum) == 11:#注册手机号必须是11位
                # 查询手机号是否唯一
                sql = "select phone from user"  # sql
                cursor.execute(sql)  # 执行
                data = cursor.fetchall()  # 得到全部数据
                if ( '('+ zcphonenum +',)') not in str(data):
                    if len(self.yzm_1) != 0:#查看验证码是否存在
                        zcyzm = self.zcyzm.text()#注册验证码
                        yzm_3 = ''#定义字符串
                        for i in range(len(self.yzm_1)):#循环
                            yzm_3 = str(yzm_3) + str(self.yzm_1[i])#使yzm_1数组数据变为字符串
                        if zcyzm == yzm_3:#判断文本框里的验证码和随机生成的验证码是否相同
                            sql = "insert into user(ur_name,ur_zh,ur_password,phone) values(%s,%s,%s,%s)"  # sql语句
                            cursor.execute(sql, (zcyhm,zcusername,zcpassword1,zcphonenum))  #执行sql语句
                            lj.commit()#保存到数据库
                            cursor.close()#关闭游标
                            lj.close()# 关闭数据库

                            information = QtWidgets.QMessageBox.information(self,"恭喜", "账号注册成功！是否录入人脸？否则返回登录界面", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)#提示框
                            if information == QMessageBox.Yes:#点击yes
                                self.shujubaocun()
                                self.xunlian()
                                information = QtWidgets.QMessageBox.information(self,"恭喜", "录入成功", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)#提示框
                                if information ==QMessageBox.Yes:
                                    self.fanhui()



                            elif information == QMessageBox.No:#点击no
                                self.fanhui()#使用返回函数返回到登录界面
                        else:#验证码出错
                            QtWidgets.QMessageBox.warning(self, "警告", "验证码错误。", QtWidgets.QMessageBox.Yes)#提示框

                    else:#未点击按钮
                        QtWidgets.QMessageBox.warning(self, "警告", "未获取验证码，请获取验证码",
                                                      QtWidgets.QMessageBox.Yes)  # 消息提示框

                else:
                    warning = QtWidgets.QMessageBox.warning(self, "警告", "该手机号已注册，是否返回登录？", QtWidgets.QMessageBox.Yes,QtWidgets.QMessageBox.No)#是否返回到登录界面
                    if warning == QMessageBox.Yes:
                        self.fanhui()  # 使用返回函数返回到登录界面

            else:
                QtWidgets.QMessageBox.warning(self, "警告", "无效手机号，请重新输入。", QtWidgets.QMessageBox.Yes)#提示框


        elif zcpassword1 != zcpassword2:
            QtWidgets.QMessageBox.warning(self, "警告", "账号密码不一致！请重新输入", QtWidgets.QMessageBox.Yes)#失败提示框

#验证码函数
    def yzm(self):
        #状态转换
        statusStr = {
            '0': '短信发送成功',
            '-1': '参数不全',
            '-2': '服务器空间不支持,请确认支持curl或者fsocket,联系您的空间商解决或者更换空间',
            '30': '密码错误',
            '40': '账号不存在',
            '41': '余额不足',
            '42': '账户已过期',
            '43': 'IP地址限制',
            '50': '内容含有敏感词'
        }

        smsapi = "http://api.smsbao.com/"# 短信平台账号
        user = '17687030192'# 短信平台密码
        password = md5('********')# 要发送的短信内容
        # content = '超市系统，本次的验证码为:'.join(str(yzm)) jion会让汉子也跟着循环
        self.yzm_1 = []  # 数组类型
        for i in range(0, 5):  # 循环
            self.yzm_1.append(random.randint(0, 9))  # 得到五个随机数的数列

        content = '超市系统，本次的验证码为:'#短信文字内容
        yzm_2 = ''#定义字符串，要发送的代码
        for i in range(len(self.yzm_1)):#循环获取随机数组中的数
            yzm_2 = str(yzm_2) + str(self.yzm_1[i])#使数组变成字符串
        content = content + yzm_2#信息 = 文本 + 验证码
        print(content)
        zcphonenum = self.zcphonenum.text()  # 电话号码
        # 要发送短信的手机号码
        phone = zcphonenum


        data = urllib.parse.urlencode({'u': user, 'p': password, 'm': phone, 'c': content})#账号密码登录发送信息
        send_url = smsapi + 'sms?' + data
        response = urllib.request.urlopen(send_url)#请求网址
        the_page = response.read().decode('utf-8')#解码
        QtWidgets.QMessageBox.information(self, "提示",statusStr[the_page], QtWidgets.QMessageBox.Yes)#短信发送提示

class Window_wjmm(QtWidgets.QMainWindow,u3):#忘记密码界面
    global yzm_1#定义全局变量
    # seyzm_1 = []  # 数组类型


    def __init__(self):#对象初始化
        super(Window_wjmm, self).__init__()  # 子类继承父类init方法

        self.setupUi(self)
        # self.ui = loadUiType('忘记密码.ui')  # 忘记密码界面路径连接
        self.pushButton_1.clicked.connect(self.yzm2)  # 按钮1连接yzm函数
        self.pushButton.clicked.connect(self.xiugaimm)  # 按钮2连接xiugaimm函数
        self.pushButton_3.clicked.connect(self.fanhui)  # 按钮3连接fanhui函数

    # 验证码函数
    def yzm2(self):
        # 状态转换
        statusStr = {
            '0': '短信发送成功',
            '-1': '参数不全',
            '-2': '服务器空间不支持,请确认支持curl或者fsocket,联系您的空间商解决或者更换空间',
            '30': '密码错误',
            '40': '账号不存在',
            '41': '余额不足',
            '42': '账户已过期',
            '43': 'IP地址限制',
            '50': '内容含有敏感词'
        }

        smsapi = "http://api.smsbao.com/"  # 短信平台账号
        user = '17687030192'  # 短信平台密码
        password = md5('********')  # 要发送的短信内容
        # content = '超市系统，本次的验证码为:'.join(str(yzm)) jion会让汉字也跟着循环
        self.yzm_1 = []  # 数组类型
        for i in range(0, 5):  # 循环
            self.yzm_1.append(random.randint(0, 9))  # 得到五个随机数的数列

        content = '超市系统，本次的验证码为:'  # 短信文字内容
        yzm_2 = ''  # 定义字符串，要发送的代码
        for i in range(len(self.yzm_1)):  # 循环获取随机数组中的数
            yzm_2 = str(yzm_2) + str(self.yzm_1[i])  # 使数组变成字符串
        content = content + yzm_2  # 信息 = 文本 + 验证码




        # print(content)
        wjmmphone = self.wjmmphone.text()  # 电话号码
        # 要发送短信的手机号码
        phone = wjmmphone

        data = urllib.parse.urlencode({'u': user, 'p': password, 'm': phone, 'c': content})#账号密码登录发送信息
        send_url = smsapi + 'sms?' + data
        response = urllib.request.urlopen(send_url)#请求网址
        the_page = response.read().decode('utf-8')#解码
        QtWidgets.QMessageBox.information(self, "提示",statusStr[the_page], QtWidgets.QMessageBox.Yes)#短信发送提示



    def fanhui(self):#定义返回登录界面的函数
        self.a=LoginWin()# a = 登录函数
        self.close()#关闭自己
        self.a.show()#打开登录

    def xiugaimm(self):#修改密码函数
        lj = pymysql.connect(host="localhost", user="root", passwd="z12j34y56", database="bigzy",
                             charset="utf8")  # 连接数据库
        cursor = lj.cursor()  # 定义游标
        ur_password = self.wjmmxmm.text()  # 获取新密码文本内容
        ur_password2 = self.wjmmxmm2.text() #获取确认密码文本内容
        ur_zh = self.wjmmzh.text()  # 获取账号文本内容
        wjmmphone = self.wjmmphone.text()#获取电话


        if len(ur_zh) == 0:#账号输入为0
            QtWidgets.QMessageBox.information(self, "警告", "账号为空！",
                                              QtWidgets.QMessageBox.Yes)  # 消息提示框
        else:
            sql = "select * from user where ur_zh = %s "  # mysql查询语句
            cursor.execute(sql, (ur_zh))  # 执行sql语句
            data = cursor.fetchone()  # 得到其中一条数据
            if data:#数据存在

                if len(ur_password) != 0:#新密码不为0
                    sql = "select phone from user where ur_zh = %s "  # mysql查询语句
                    cursor.execute(sql, (ur_zh))  # 执行sql语句
                    data = cursor.fetchone()#得到其中一条语句

                    if ( '('+ wjmmphone +',)') in str(data):#判断输入的手机号是否对

                        if ur_password == ur_password2:#判断两次密码一不一样

                            try:#判断是否点击了验证码按钮

                                wjmmyzm = self.wjmmyzm.text()  # 忘记密码验证码
                                yzm_3 = ''#定义字符串
                                for i in range(len(self.yzm_1)):#循环
                                    yzm_3 = str(yzm_3) + str(self.yzm_1[i])#获取随机生成的字符串

                                if len(wjmmyzm) == 5:#判断验证码长度是否为五

                                    if wjmmyzm == yzm_3:  # 判断文本框里的验证码和随机生成的验证码是否相同
                                        sql = "update user set ur_password = %s where ur_zh = %s "  # mysql修改语句
                                        cursor.execute(sql, (ur_password,ur_zh))  # 执行sql语句
                                        information = QtWidgets.QMessageBox.information(self, "提示", "修改成功!是否返回登录",
                                                                          QtWidgets.QMessageBox.Yes,QtWidgets.QMessageBox.No)  # 查询成功消息提示框
                                        lj.commit()  # 数据库操作完成
                                        lj.close()  # 关闭连接
                                        cursor.close()  # 关闭游标

                                        if information == QMessageBox.Yes:#点击yes
                                            self.fanhui()#返回到登录界面
                                    else:#验证码不相同
                                        QtWidgets.QMessageBox.warning(self, "警告", "验证码出错！",
                                                                          QtWidgets.QMessageBox.Yes)# 消息提示框
                                else:#验证码长度不为五
                                    QtWidgets.QMessageBox.warning(self, "警告", "验证码出错！",
                                                                  QtWidgets.QMessageBox.Yes)  # 消息提示框
                            except:#验证码按钮未点击
                                QtWidgets.QMessageBox.warning(self, "警告", "未获取验证码，请获取验证码",
                                                              QtWidgets.QMessageBox.Yes)#消息提示框



                        else:#两次密码不相同
                             QtWidgets.QMessageBox.warning(self, "警告", "两次密码不相同",
                                                          QtWidgets.QMessageBox.Yes,)#信息提示框


                    else:#手机号不存在数据库中
                         QtWidgets.QMessageBox.warning(self, "警告", "手机号发生错误",
                                                          QtWidgets.QMessageBox.Yes,)  # 无效手机号提示

                else:#密码文本输入为0
                    QtWidgets.QMessageBox.warning(self, "警告", "密码不可为空",
                                                      QtWidgets.QMessageBox.Yes)  # 消息提示框

            else:#账号不存在
                QtWidgets.QMessageBox.warning(self, "警告", "账号不存在",
                                                  QtWidgets.QMessageBox.Yes)  # 消息提示框



class Window_gl(QtWidgets.QMainWindow,u4):#管理界面类
    #界面以及按钮连接
    def __init__(self):#对象初始化

        super(Window_gl, self).__init__()  # 子类继承父类init方法

        self.setupUi(self)
        # self.ui = loadUiType('商品管理.ui')
        # self.ui = loadUiType('商品管理.ui')  # 商品管理界面路径连接
        self.show_spgl()#商品管理表显示


        i = 1
        self.spider1()
        if i >0:
            t = Timer(36400, self.spider1)
            t.start()
            # i += 1
            # if i == 50:
            #     break







        self.cxp1.clicked.connect(self.chaxun)#查询按钮1连接chaxun函数
        self.cxp2.clicked.connect(self.chaxun2)#查询按钮2连接chaxun2函数
        self.scp1.clicked.connect(self.shanchu)#删除按钮1连接shanchu函数
        self.scp2.clicked.connect(self.shanchu2)#删除按钮1连接shanchu函数
        self.xgcxp1.clicked.connect(self.xgchaxun)#修改查询按钮1连接xgchaxun函数
        self.xgcxp2.clicked.connect(self.xgchaxun2)#修改查询按钮2连接xgchaxun2函数
        self.xgp1.clicked.connect(self.xiugai)#修改按钮连接xiugai函数
        self.zjp1.clicked.connect(self.zengjia)#增加按钮连接zengjia函数


        self.xsp1.clicked.connect(self.spxs)#销售按钮p1连接spxs函数
        self.jhp1.clicked.connect(self.spjh)#进货按钮p1连接spjh函数
        self.gqp2.clicked.connect(self.spgq2)#过期按钮p2连接spgq2函数
#定时执行爬虫


    # 指定1秒后执行print_time函数



#数据表商品管理显示
    def show_spgl(self):
        lj = pymysql.connect(host="localhost", user="root", passwd="z12j34y56", database="bigzy",
                             charset="utf8")  # 连接数据库
        cursor = lj.cursor()  # 定义游标

        sql = "select * from spgl"#sql数据
        cursor.execute(sql)#执行sql语句

        data = cursor.fetchall()  # 获取查询到的全部数据，是以二维元组的形式存储的，所以读取需要使用data[i][j] 下标定位

        if data:#数据存在
            self.tableWidget_5.setRowCount(0)#不设置限制
            self.tableWidget_5.insertRow(0)
            for row, form in enumerate(data):#循环
                for column, item in enumerate(form):#循环
                    #将数据写入tableWidget_5
                    self.tableWidget_5.setItem(row, column, QtWidgets.QTableWidgetItem(str(item)))
                    column += 1
                row_position = self.tableWidget_5.rowCount()
                self.tableWidget_5.insertRow(row_position)


#数据表增加显示
    def show_zj(self):
        lj = pymysql.connect(host="localhost", user="root", passwd="z12j34y56", database="bigzy",
                             charset="utf8")  # 连接数据库
        cursor = lj.cursor()  # 定义游标
        sql = "select * from spgl"#sql查询语句
        cursor.execute(sql)#执行

        data = cursor.fetchall()  # 获取查询到的数据，是以二维元组的形式存储的，所以读取需要使用data[i][j] 下标定位

        if data:#数据存在
            self.tableWidget_zj.setRowCount(0)#不设置数据数量限制
            self.tableWidget_zj.insertRow(0)
            for row, form in enumerate(data):#循环
                for column, item in enumerate(form):
                    #写入数据
                    self.tableWidget_zj.setItem(row, column, QtWidgets.QTableWidgetItem(str(item)))
                    column += 1
                row_position = self.tableWidget_zj.rowCount()
                self.tableWidget_zj.insertRow(row_position)
        lj.close()  # 关闭连接
        cursor.close()  # 关闭游标


#查询
    def chaxun(self):
        lj = pymysql.connect(host="localhost", user="root", passwd="z12j34y56", database="bigzy",
                             charset="utf8")  # 连接数据库
        cursor = lj.cursor()  # 定义游标
        sql = "select * from spgl where sp_no=%s"#mysql查询语句
        no = self.cx1.text()#获取cx1文本内容
        cursor.execute(sql, (no))#执行sql语句
        data = cursor.fetchone()#得到其中一条数据
        if data:#数据存在
            self.cx3.setText(str(data[0]))#cx3显示商品编号
            self.cx4.setText(data[1])#cx4显示商品名称
            self.cx5.setText(str(data[2]))#cx5显示商品数量
            self.cx6.setText(str(data[3]))#cx6显示条目更新日期
            QtWidgets.QMessageBox.information(self, "提示", "查询成功!",
                                          QtWidgets.QMessageBox.Yes)#查询成功消息提示框
        else:
            QtWidgets.QMessageBox.warning(self, "警告", "没有该物品",#查询失败消息提示框
                                          QtWidgets.QMessageBox.Yes)
        self.show_spgl()


    def chaxun2(self):#chaxun2函数
        lj = pymysql.connect(host="localhost", user="root", passwd="z12j34y56", database="bigzy",
                             charset="utf8")  # 连接数据库
        cursor = lj.cursor()  # 定义游标
        sql = "select * from spgl where sp_name=%s"#sql语句
        name = self.cx2.text()#获取文本内容
        cursor.execute(sql, (name))#执行sql语句
        data = cursor.fetchone()#得到其中一条数据
        if data:#数据存在
            self.cx3.setText(str(data[0]))#cx3显示商品编号
            self.cx4.setText(data[1])#cx4显示商品名称
            self.cx5.setText(str(data[2]))#cx5显示商品数量
            self.cx6.setText(str(data[3]))#cx6显示条目更新日期
            QtWidgets.QMessageBox.information(self, "提示", "查询成功!",
                                              QtWidgets.QMessageBox.Yes)#查询成功提示框
        else:
            QtWidgets.QMessageBox.warning(self, "警告", "没有该物品",
                                          QtWidgets.QMessageBox.Yes)#查询失败提示框
        self.show_spgl()
 #删除
    def shanchu(self):
        no = self.ui.sc2.text()#获取sc2文本框内容

        warning = QtWidgets.QMessageBox.warning(self, "提示", "确定要删除该内容么？",
                                                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)#删除提示框
        if warning == QMessageBox.Yes:#判断 点击yes
            lj = pymysql.connect(host="localhost", user="root", passwd="z12j34y56", database="bigzy",
                                 charset="utf8")  # 连接数据库
            cursor1 = lj.cursor()#定义游标
            sql1 = "select * from spgl where sp_no=%s"#sql语句
            cursor1.execute(sql1, (no))#执行sql
            data = cursor1.fetchone()#得到一条数据
            if data:#数据是否存在，存在执行
                self.sc3_2.setText(str(data[0]))#显示商品编号
                self.sc4_2.setText(data[1])#显示商品名称
                self.sc5_2.setText(str(data[2]))#显示商品数量
                self.sc6_2.setText(str(data[3]))#显示条目更新日期
            cursor = lj.cursor()  # 定义游标
            sql = "delete from spgl where sp_no = %s"#sql语句
            cursor.execute(sql, (no))#执行sql语句


            QtWidgets.QMessageBox.information(self, "提示", "删除成功",
                                          QtWidgets.QMessageBox.Yes)#消息提示框
            lj.commit()#数据库操作完成
            lj.close()#关闭连接
            cursor.close()#关闭游标
            #表格同步
            self.show_spgl()
            self.show_zj()

    def shanchu2(self):#删除2函数
        name = self.sc1.text()#获取文本框内容，name查询

        warning = QtWidgets.QMessageBox.warning(self, "提示", "您确定要删除该内容么？",
                                                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)#消息提示框
        if warning == QMessageBox.Yes:
            lj = pymysql.connect(host="localhost", user="root", passwd="z12j34y56", database="bigzy",
                                 charset="utf8")  # 连接数据库
            cursor = lj.cursor()  # 定义游标
            sql = "delete from spgl where sp_name=%s"#sql语句
            cursor.execute(sql, (name))#执行sql

            cursor1 = lj.cursor()#游标
            sql1 = "select * from spgl where sp_name=%s"#sql语句
            cursor1.execute(sql1, (name))#执行语句
            data = cursor1.fetchone()#得到其中一条数据
            if data:#数据是否存在，存在则
                self.sc3_2.setText(str(data[0]))#显示编号
                self.sc4_2.setText(data[1])#显示名称
                self.sc5_2.setText(str(data[2]))#显示数量
                self.sc6_2.setText(str(data[3]))#显示条目日期
            QtWidgets.QMessageBox.warning(self, "提示", "删除成功！",
                                          QtWidgets.QMessageBox.Yes)#信息框

            lj.commit()#数据保存到库
            lj.close()#关闭连接
            cursor.close()#关闭游标
            #表格同步
            self.show_spgl()
            self.show_zj()

# 修改的查询
    def xgchaxun(self):
            lj = pymysql.connect(host="localhost", user="root", passwd="z12j34y56", database="bigzy",
                                 charset="utf8")  # 连接数据库
            cursor = lj.cursor()  # 定义游标
            sql = "select * from spgl where sp_no=%s"#sql语句
            no = self.xgcx1.text()#获取修改查询文本框内容
            cursor.execute(sql, (no))#执行sql语句
            data = cursor.fetchone()#得到其中一条语句
            if data:#判断是否存在，存在则
                #写入数据
                self.xg1_2.setText(str(data[0]))
                self.xg1_3.setText(data[1])
                self.xg1_4.setText(str(data[2]))
                self.xg1_5.setText(str(data[3]))
                QtWidgets.QMessageBox.information(self, "提示", "查询成功!",
                                                  QtWidgets.QMessageBox.Yes)#查询成功提示框
            else:
                QtWidgets.QMessageBox.warning(self, "警告", "没有该物品",
                                              QtWidgets.QMessageBox.Yes)#失败提示框

    def xgchaxun2(self):#修改查询函数2
            lj = pymysql.connect(host="localhost", user="root", passwd="z12j34y56", database="bigzy",
                                 charset="utf8")  # 连接数据库
            cursor = lj.cursor()  # 定义游标
            sql = "select * from spgl where sp_name=%s"#sql语句
            name = self.xgcx2.text()#获取文本框内容
            cursor.execute(sql, (name))#执行sql语句
            data = cursor.fetchone()#得到其中一条数据
            if data:#判断，数据存在则
                #显示，写入数据
                self.xg1_2.setText(str(data[0]))
                self.xg1_3.setText(data[1])
                self.xg1_4.setText(str(data[2]))
                self.xg1_5.setText(str(data[3]))
                QtWidgets.QMessageBox.information(self, "提示", "查询成功!",
                                                  QtWidgets.QMessageBox.Yes)#查询成功信息提示框
            else:
                QtWidgets.QMessageBox.warning(self, "警告", "没有该物品",
                                              QtWidgets.QMessageBox.Yes)#查询失败信息提示框
#修改
    def xiugai(self):
        no = self.xgcx1.text()#商品编号
        a1 = self.xg1.text()#编号
        a2 = self.xg2.text()#名称
        a3 = self.xg3.text()#数量
        a4 = self.xg4.text()#时间

        lj = pymysql.connect(host="localhost", user="root", passwd="z12j34y56", database="bigzy",
                             charset="utf8")  # 连接数据库
        cursor = lj.cursor()  # 定义游标
        sql = "update spgl set sp_no=%s,sp_name=%s,sp_qty=%s,tl_time=now() where sp_no=%s"#sql语句
        cursor.execute(sql, (a1, a2, a3,no))#执行
        # sql1 = "select tl_time from spgl where sp_no=%s"#sql语句
        # data = cursor.execute(sql1,(no))
        # 显示修改后的数据
        self.xg1_6.setText(str(a1))
        self.xg1_7.setText(a2)
        self.xg1_8.setText(str(a3))
        # self.xg1_9.setText(str(data))
        QtWidgets.QMessageBox.information(self, "提示", "修改成功!",
                                              QtWidgets.QMessageBox.Yes)#修改成功提示框

        lj.commit()#保存到数据库
        lj.close()#关闭连接
        cursor.close()#关闭游标
        #表格同步
        self.show_spgl()
        self.show_zj()
#增加
    def zengjia(self):
        #获取文本框内容
        a1 = self.zj1.text()
        a2 = self.zj2.text()
        a3 = self.zj3.text()

        lj = pymysql.connect(host="localhost", user="root", passwd="z12j34y56", database="bigzy",
                             charset="utf8")  # 连接数据库
        cursor = lj.cursor()#定义游标
        sql = "insert into spgl(sp_no,sp_name,sp_qty,tl_time) values(%s,%s,%s,now())"#sql语句
        cursor.execute(sql, (a1, a2, a3))#执行
        lj.commit()#保存到数据库
        lj.close()  # 关闭连接
        cursor.close()  # 关闭游标
        #表格同步更新
        self.show_spgl()
        self.show_zj()





#商品销售记录表
    def spxs(self):
        #文本框内容获取
        a1 = self.xs1.text()
        a2 = self.xs2.text()
        a3 = self.xs3.text()




        lj = pymysql.connect(host="localhost", user="root", passwd="z12j34y56", database="bigzy",
                             charset="utf8")  # 连接数据库
        cursor = lj.cursor()#定义游标
        if len(a1) != 0:#编号不为空
            sql = "select * from spgl where sp_no = %s "#sql语句
            cursor.execute(sql,(a1))#执行
            # 获取查询到的数据，是以二维元组的形式存储的，所以读取需要使用data[i][j] 下标定位
            if cursor.fetchone():#如果数据（商品）存在
                if len(a2) != 0:#商品售价不为空
                    if len(a3) != 0:#数量不为空
                        a4 = int(a3) * float(a2)#计算总价
                        sql = "insert into spxs(spo_no,spo_sjia,spo_qty,spo_zjia,spo_time) values(%s,%s,%s,%s,now())"#sql语句
                        cursor.execute(sql, (a1, a2, a3, a4))#执行

                        # sql = "update spgl set sp_qty = (spgl.sp_qty-%s/2) where sp_no = %s;"
                        # cursor.execute(sql,(a3,a1))
                        lj.commit()#保存到数据库


                    else:#数量，a3文本框为空时，默认数量为1
                        sql = "insert into spxs(spo_no,spo_sjia,spo_qty,spo_zjia,spo_time) values(%s,%s,%s,%s,now())"  # sql语句
                        cursor.execute(sql, (a1, a2,'1',a2))  # 执行

                        # sql = "update spgl set sp_qty = (sp_qty) where sp_no = %s;"
                        # cursor.execute(sql, (a1))
                        lj.commit()  # 保存到数据库

                    sql = "select * from spxs"#sql查询语句
                    cursor.execute(sql)#执行


                    data = cursor.fetchall()  # 获取查询到的全部数据，是以二维元组的形式存储的，所以读取需要使用data[i][j] 下标定位

                    if data:#如果数据存在
                        self.tableWidget_spxs.setRowCount(0)#数据数量无限制
                        self.tableWidget_spxs.insertRow(0)
                        for row, form in enumerate(data):#循环
                            for column, item in enumerate(form):
                                #写入所有得到的数据
                                self.tableWidget_spxs.setItem(row, column,
                                                                 QtWidgets.QTableWidgetItem(str(item)))
                                column += 1
                            row_position = self.tableWidget_spxs.rowCount()
                            self.tableWidget_spxs.insertRow(row_position)
                    lj.close()  # 关闭连接
                    cursor.close()  # 关闭游标

                else:#价格为空
                    QtWidgets.QMessageBox.warning(self, "警告", "销售单价不可为空！",
                                                    QtWidgets.QMessageBox.Yes)#提示框

            else:#商品不存在
                QtWidgets.QMessageBox.warning(self, "警告", "商品不存在",
                                    QtWidgets.QMessageBox.Yes)  # 提示框

        else:#编号栏为空
            QtWidgets.QMessageBox.warning(self, "警告", "商品未输入！",
                                                QtWidgets.QMessageBox.Yes)#提示框


#商品进货
    def spjh(self):
        #获取文本框内容
        a1 = self.jh1.text()
        a2 = self.jh2.text()
        a3 = self.jh3.text()
        a4 = int(a3) * float(a2)#总价
        a5 = self.jh4.text()#新商品名称

        lj = pymysql.connect(host="localhost", user="root", passwd="z12j34y56", database="bigzy",
                             charset="utf8")  # 连接数据库
        cursor = lj.cursor()#定义游标

        if len(a1) != 0:#编号不为空

            if len(a2) != 0:#进价不为空

                if len(a3) != 0:#数量不为空

                    sql = "select * from spgl where sp_no = %s "#sql查询语句
                    cursor.execute(sql, (a1))#定义游标

                    if cursor.fetchone():#sql语句获取到数据时

                        sql = "insert into spjh(spi_no,spi_jjia,spi_qty,spi_zjia,tl_time) values(%s,%s,%s,%s,now())"#sql语句
                        cursor.execute(sql, (a1, a2, a3, a4))#执行
                        lj.commit()#保存到数据库

                    else:#商品管理无该商品
                        information = QtWidgets.QMessageBox.information(self, "提示", "无该商品信息，是否添加新商品",
                                            QtWidgets.QMessageBox.Yes,QtWidgets.QMessageBox.No)  # 提示框
                        if information == QtWidgets.QMessageBox.Yes:
                            if len(a5) != 0:

                                sql = "insert into spjh(spi_no,spi_jjia,spi_qty,spi_zjia,tl_time) values(%s,%s,%s,%s,now())" # sql语句
                                cursor.execute(sql, (a1, a2, a3, a4))  # 执行
                                lj.commit()  # 保存到数据库
                                sql = "insert into spgl(sp_no,sp_name,sp_qty,tl_time) values(%s,%s,%s,now())"  # sql语句
                                cursor.execute(sql, (a1, a5, a3))  # 执行
                                lj.commit()  # 保存到数据库

                            else:
                                QtWidgets.QMessageBox.warning(self, "警告", "新商品名称不可为空。请输入",
                                                    QtWidgets.QMessageBox.Yes)  # 提示框



                else:#数量为空
                    QtWidgets.QMessageBox.warning(self, "警告", "数量为空！",
                                                    QtWidgets.QMessageBox.Yes)#提示框

            else:#进价为空
                QtWidgets.QMessageBox.warning(self, "警告", "进价为空！",
                                    QtWidgets.QMessageBox.Yes)  # 提示框

        else:#编号为空
            QtWidgets.QMessageBox.warning(self, "警告", "商品未输入！",
                                                QtWidgets.QMessageBox.Yes)#提示框

        sql = "select * from spjh"#sql查询语句
        cursor.execute(sql)#执行

        data = cursor.fetchall()  # 获取查询到的数据，是以二维元组的形式存储的，所以读取需要使用data[i][j] 下标定位
        #数据存在的话，显示到表里去
        if data:
            self.tableWidget_spjh.setRowCount(0)#数据数目不限制
            self.tableWidget_spjh.insertRow(0)
            for row, form in enumerate(data):#循环
                for column, item in enumerate(form):
                    #写入数据
                    self.tableWidget_spjh.setItem(row, column, QtWidgets.QTableWidgetItem(str(item)))
                    column += 1
                row_position = self.tableWidget_spjh.rowCount()
                self.tableWidget_spjh.insertRow(row_position)
        lj.close()  # 关闭连接
        cursor.close()  # 关闭游标



#商品过期
    def spgq2(self):
        #获取文本框内容
        a3 = self.gq3.text()
        a4 = self.gq4.text()
        a5 = self.gq5.text()
        lj = pymysql.connect(host="localhost", user="root", passwd="z12j34y56", database="bigzy",
                             charset="utf8")  # 连接数据库
        cursor = lj.cursor()  # 定义游标
        information = QtWidgets.QMessageBox.information(self, "提示", "您确定要添加新的过期商品么么？",
                                                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)#提示框
        if information == QMessageBox.Yes:#判断 yes

            if len(a3) != 0:#编号不为空

                    if len(a5) != 0:#数量不为空

                        if len(a4) !=0:#商品名称不为空
                            sql = "insert into spgq(sp_no,sp_name,sp_qtyg) values(%s,%s,%s)"#sql语句
                            cursor.execute(sql, (a3,a4,a5))#执行
                            QtWidgets.QMessageBox.information(self, "提示", "添加成功",
                                                QtWidgets.QMessageBox.Yes)#提示框
                            lj.commit()#保存到数据库

                        else:#商品名称为空
                            sql = "select * from spgl where sp_no = %s"#sql语句
                            cursor.execute(sql, (a3))  # 执行
                            if cursor.fetchone():#数据存在
                                sql = "select sp_name from spgl where sp_no = %s"#得到商品编号对应的商品名称
                                cursor.execute(sql, (a3))#执行
                                data = cursor.fetchone()#得到数据
                                data = str(data)#转换为字符串
                                data = data[2:-3]#切片得到商品名称

                                sql = "insert into spgq(sp_no,sp_name,sp_qtyg) values(%s,%s,%s)"  # sql语句
                                cursor.execute(sql, (a3,data,a5))  # 执行
                                QtWidgets.QMessageBox.information(self, "提示", "添加成功",
                                                                  QtWidgets.QMessageBox.Yes)  # 提示框
                                lj.commit()  # 保存到数据库

                            else:#商品名称未填，或者spgl表里没有该数据
                                QtWidgets.QMessageBox.warning(self, "警告", "未找到该商品或商品名称未填！",
                                                            QtWidgets.QMessageBox.Yes)  # 提示框

                    else:#数量为空
                        QtWidgets.QMessageBox.warning(self, "警告", "数量未输入！",
                                                   QtWidgets.QMessageBox.Yes)  # 提示框

            else:#编号为空
                QtWidgets.QMessageBox.warning(self, "警告", "商品未输入！",
                                            QtWidgets.QMessageBox.Yes)  # 提示框
            #过期表显示数据
            sql = "select * from spgq"#sql语句
            cursor.execute(sql)#执行

            data = cursor.fetchall()  # 获取查询到的全部数据，是以二维元组的形式存储的，所以读取需要使用data[i][j] 下标定位

            if data:#数据存在
                self.tableWidget_spgq.setRowCount(0)#数据数量无限制
                self.tableWidget_spgq.insertRow(0)
                for row, form in enumerate(data):#循环
                    for column, item in enumerate(form):
                        #写入数据
                        self.tableWidget_spgq.setItem(row, column, QtWidgets.QTableWidgetItem(str(item)))
                        column += 1
                    row_position = self.tableWidget_spgq.rowCount()
                    self.tableWidget_spgq.insertRow(row_position)
            lj.close()  # 关闭连接
            cursor.close()  # 关闭游

#爬虫
    def spider1(self):#京东top30零食

        #爬取的地址
        baseurl = "https://search.jd.com/Search?keyword=%E9%9B%B6%E9%A3%9F&qrst=1&stock=1&pvid=6ce7853633cd4f4f9859302069bf770e&psort=3&click=1"#地址
        #请求头信息，伪装成浏览器
        head = {
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36 Edg/94.0.992.50",
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-platform": "Windows",
            "sec-fetch-dest": "document",
            "sec-fetch-mode": "navigate"
            }  # 用户代理，模拟浏览器
        #发送请求
        request = urllib.request.Request(baseurl, headers=head)

        try:#打开地址
            response = urllib.request.urlopen(request)
            html = response.read().decode("utf-8")
            # print(html)


            # 全局变量，进行相关匹配
            findtitle = re.compile(r'<em><span class="p-tag" style="background-color:#c81623">(.*?)</em>',re.S)
            findprice = re.compile(r'<strong class="(.*?)"(.*?)</strong>',re.S)
            # 2.逐行解析代码
            soup = BeautifulSoup(html, 'html.parser')#解释器
            datalist = []#定义数组
            for item in soup.find_all('div', class_="gl-i-wrap"):#寻找符合相应的信息

                try:

                    data = []
                    item = str(item)
                    title = re.findall(findtitle, item)[0]#寻找符合匹配的全部数据
                    #去掉无用字符
                    title = re.sub('</span>(\s+)?', '', title)
                    title = re.sub('</font>(\s+)?', '', title)
                    title = re.sub('<font class="skcolor_ljg">(\s+)?', '', title)
                    title = title.replace('京东超市', '')
                    #写入数据
                    data.append(title)
                    #寻找符合匹配的全部数据
                    price = re.findall(findprice, item)[0]
                    # 去掉无用字符
                    price = re.sub('data-done=".*">','', price[1])
                    price = re.sub('<em>￥</em><i data-price=".*?">','', price)
                    price = re.sub('</i>','', price)
                    price = str(price)
                    data.append(price)
                    #数据汇总
                    datalist.append(data)

                except:
                    #数据爬取有部分不成功，无法避免，因为京东的开发者工具栏有一部分数据不与其他数据的匹配相同
                    #反爬虫？或者设计师故意为之
                    #未爬取到相关数据的话，自动填充
                    data = []
                    title = "title Unkonwn"
                    data.append(title)
                    price = "price Unkonwn"
                    data.append(price)
                    #数据汇总
                    datalist.append(data)

            if datalist:  # 如果数据存在
                self.tableWidget_top.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
                self.tableWidget_top.setRowCount(0)  # 数据数量无限制
                self.tableWidget_top.insertRow(0)
                for row, form in enumerate(datalist):  # 循环
                    for column, item in enumerate(form):
                        # 写入所有得到的数据
                        self.tableWidget_top.setItem(row, column,
                                                         QtWidgets.QTableWidgetItem(str(item)))
                        column += 1
                    row_position = self.tableWidget_top.rowCount()
                    self.tableWidget_top.insertRow(row_position)


        except urllib.error.URLError as e:#请求网址不成功时
            if hasattr(e, 'code'):#相关报错
                QtWidgets.QMessageBox.warning(self, "警告", e.code,
                                              QtWidgets.QMessageBox.Yes)  # 提示框
            if hasattr(e, 'reason'):#相关报错
                QtWidgets.QMessageBox.warning(self, "警告", e.reason,
                                              QtWidgets.QMessageBox.Yes)  # 提示框

#爬虫
    def spider2(self):#京东top零食
        dpdz = self.dpdz.text()#店铺地址

        if len(dpdz) != 0:
                #爬取的地址
                baseurl = dpdz
                #请求头信息，伪装成浏览器
                head = {
                    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36 Edg/94.0.992.50",
                    "sec-ch-ua-mobile": "?0",
                    "sec-ch-ua-platform": "Windows",
                    "sec-fetch-dest": "document",
                    "sec-fetch-mode": "navigate"
                    }  # 用户代理，模拟浏览器
                #发送请求
                request = urllib.request.Request(baseurl, headers=head)

                try:#打开地址
                        response = urllib.request.urlopen(request)
                        html = response.read().decode("utf-8")
                        # print(html)

                        # 全局变量，进行相关匹配
                        findtitle = re.compile(r'<a href=".*?" target="_blank">(.*?)</a>',re.S)
                        findprice = re.compile(r'<span class="jdNum" jdprice=".*?"(.*?)</span>',re.S)
                        # 2.逐行解析代码
                        soup = BeautifulSoup(html, 'html.parser')  # 解释器
                        datalist = []  # 定义数组
                        for item in soup.find_all('div', class_="gl-i-wrap"):  # 寻找符合相应的信息

                            try:

                                data = []
                                item = str(item)
                                title = re.findall(findtitle, item)[0]  # 寻找符合匹配的全部数据
                                # 去掉无用字符
                                title = re.sub('</span>(\s+)?', '', title)
                                title = re.sub('</font>(\s+)?', '', title)
                                title = re.sub('<font class="skcolor_ljg">(\s+)?', '', title)
                                title = title.replace('京东超市', '')
                                # 写入数据
                                data.append(title)
                                # 寻找符合匹配的全部数据
                                price = re.findall(findprice, item)[0]
                                # 去掉无用字符
                                price = re.sub('data-done=".*">', '', price[1])
                                price = re.sub('<em>￥</em><i data-price=".*?">', '', price)
                                price = re.sub('</i>', '', price)
                                price = str(price)
                                data.append(price)
                                # 数据汇总
                                datalist.append(data)

                            except:
                                # 数据爬取有部分不成功，无法避免，因为京东的开发者工具栏有一部分数据不与其他数据的匹配相同
                                # 反爬虫？或者设计师故意为之
                                # 未爬取到相关数据的话，自动填充
                                data = []
                                title = "title Unkonwn"
                                data.append(title)
                                price = "price Unkonwn"
                                data.append(price)
                                # 数据汇总
                                datalist.append(data)

                        if datalist:  # 如果数据存在
                            self.tableWidget_top.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
                            self.tableWidget_top.setRowCount(0)  # 数据数量无限制
                            self.tableWidget_top.insertRow(0)
                            for row, form in enumerate(datalist):  # 循环
                                for column, item in enumerate(form):
                                    # 写入所有得到的数据
                                    self.tableWidget_top.setItem(row, column,
                                                                    QtWidgets.QTableWidgetItem(str(item)))
                                    column += 1
                                row_position = self.tableWidget_top.rowCount()
                                self.tableWidget_top.insertRow(row_position)

                except urllib.error.URLError as e:#请求网址不成功时
                    if hasattr(e, 'code'):#相关报错
                        QtWidgets.QMessageBox.warning(self, "警告", e.code,
                                                      QtWidgets.QMessageBox.Yes)  # 提示框
                    if hasattr(e, 'reason'):#相关报错
                        QtWidgets.QMessageBox.warning(self, "警告", e.reason,
                                                      QtWidgets.QMessageBox.Yes)  # 提示框

        else:
            QtWidgets.QMessageBox.warning(self, "警告", "地址为空！",
                                          QtWidgets.QMessageBox.Yes)  # 提示框


class Face(QMainWindow,u1):
    global id_1
    def __init__(self):#对象初始化

        super(Face, self).__init__()  # 子类继承父类init方法


        # self.ui = loadUiType('登陆界面.ui')  # 登录界面路径加载，因为后面提示框需要参数，所以使用该ui
        self.face_shibie()#运行识别函数


    def face_shibie(self):#识别函数

        font = cv2.FONT_HERSHEY_TRIPLEX#字体显示
        # 加载训练器
        recognizer = cv2.face.LBPHFaceRecognizer_create()
        #分类器加载
        faceCascade = cv2.CascadeClassifier('./haarcascade_frontalface_alt2.xml')
        #读入训练好的数据
        recognizer.read('./trainer/people.yml')  #
        cap = cv2.VideoCapture(0)

        #该方法循环不成功，所以增加计算量来让该步骤成功
        # yml_path = 'trainer'
        # # 所有yml文件的路径
        # all_yml_paths = [os.path.join(yml_path, f) for f in os.listdir(yml_path)]
        # for each_yml in all_yml_paths:
        #     recognizer.read(each_yml)#读入所有文件
        #     print(each_yml)

        #定义几个int变量
        count2 = 0#用于循环成功识别到用户的
        count3 = 0#用于成功识别到人但不是数据库中的用户的
        count4 = 0#用于没有识别出人脸的

        while True:  # 死循环，不让摄像头一闪而逝
            # cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
            ok, img = cap.read()  # 得到摄像头的图片img和状态，视频由一帧一帧图像构成

            # if img is None:
            #     print("img is none")
            # else:
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 将img转换为灰度图像

            # 用来识别照片中的人脸
            faces = faceCascade.detectMultiScale(
                gray,
                scaleFactor=1.05,  # 每次图像尺寸减小的比例，越大越检测不到
                minNeighbors=5,  # 检测五次，五次都有才能是人脸
                minSize=(32, 32)  # 图片最小尺寸
            )

            for (x, y, w, h) in faces:  #
                # 将数据保存到指定文件夹下 文件名为：user+数字+字符串.jpg
                cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)  # 矩形，将人脸框起来，框选的目
                #获取得到的人脸以及置信水平（准确率）
                id, confidence = recognizer.predict(gray[y:y + h, x:x + w])
                # print(id,confidence)
                #判断置信水平，太大的话难以识别成功，太小又会识别错误
                if confidence > 50:
                   #显示识别出来的那个id
                   cv2.putText(img, str(id), (x + 5, y - 5), font, 1, (233, 255, 0), 1)
                   count2 += 1
                   print(count2)

                else:#置信水平小于50
                    #无用户或者未识别出来，显示unknow，
                    cv2.putText(img, "unknow", (x + 5, y - 5), font, 1, (233, 255, 0), 1)
                    count3 +=1
                    # print(count2)
                # print(id, confidence)

            #显示摄像头
            cv2.imshow('video', img)
            #不断刷新图像，频率为1ms，以达到视频的效果
            key = cv2.waitKey(1)

            #未识别到人脸
            if len(faces) ==0:
                count4 += 1

            if count4 == 100:#当count达到100时，执行下面
                QtWidgets.QMessageBox.warning(self, "警告", '未检测到人脸，请查看摄像头或者换个环境试试叭！',
                                              QtWidgets.QMessageBox.Yes)  # 提示框
                id = ''#因为图片未检测到人脸，则id也没有，所以定义一个id（空字符），用于后面判断
                cap.release()#关闭摄像头
                cv2.destroyAllWindows()#关闭窗口
                break#跳出循环

            if count3 == 100:#当count达到100时，执行下面
                QtWidgets.QMessageBox.warning(self, "警告",'未识别成功！',
                                              QtWidgets.QMessageBox.Yes)  # 提示框
                id = ''#未识别成功，定义一个id（空字符），用于后面判断
                cap.release()#关闭摄像头
                cv2.destroyAllWindows()#关闭窗口
                break#跳出循环



            #识别成功
            if count2 == 30:#当识别成功的次数达到50时
                break#跳出循环，id也获取到，所以不用定义

            if key == 27:#按键盘esc也可退出程序

                id = ''#定义一个id（空字符），用于后面判断
                break#跳出循环

        cap.release()#关闭摄像头
        cv2.destroyAllWindows()#关闭窗口

        lj = pymysql.connect(host="localhost", user="root", passwd="z12j34y56", database="bigzy",
                             charset="utf8")  # 连接数据库
        cursor = lj.cursor()  # 定义游标
        sql = "select ur_zh from user"#查询账号
        cursor.execute(sql)#执行
        data = cursor.fetchall()##得到全部数据
        lj.commit()#上传
        lj.close()#关闭链接

        id_1 = []#定义一个数组
        # id = tuple((3,))
        data = list(data)#将元组类型data转换为数组，而里面的元素还是元组（特别注意）
        for i in range(len(data)):#循环得到data中的值
            id_1.append(data[i])#将data存入id_1中
        id = tuple((id,))#将人脸识别的id转换为数组类型，因为id_1中数据为"(1,)"这种类型，故加括号
        # cv2.imshow('video', img)
        # print(id in id_1)
        #判断id在不在id_1中，即识别成不成功
        if id in id_1:
            self.w = Window_gl()  # 调用管理界面函数
            self.l = LoginWin()
            self.l.hide()#关闭登录界面
            self.w.show()  # 主窗口（管理界面）打开
        else:
            QtWidgets.QMessageBox.warning(self, "警告", '未识别成功！',
                                          QtWidgets.QMessageBox.Yes)  # 提示框
            self.l = LoginWin()#登陆界面
            self.l.show()#显示




        
if __name__ == '__main__':#任务执行
    app = QtWidgets.QApplication(sys.argv)#实例化一个应用对象（打开一个类似于窗口的东西）
    wm = LoginWin()#令wm = 登录函数
    wm.show()#展示登录界面
    sys.exit(app.exec_())#程序一直循环运行直到主窗口被关闭终止进程，反映程序终止的状态的